#include "config.h"
#include <cmath>
#include <omp.h>
#include <ctime>
#include "cl_scene.h"
#include "photon_map.h"
#include "reflection.h"
#include "random_number_generator_mt19937.h"
#include "permuted_halton.h"


void estimate_e(photon_map_t* photon_map,HybridLookupAccelerator<photon_t>* map,int count,
				const point3f_t& p, const normal3f_t& n,
				spectrum_t* ret)
{
	if(!map) {vclr(*ret);return;}
	//lookup nearby photons at irradiance computation point
	photon_process_data_t proc_data;	

	photon_process_data_init(&proc_data,photon_map->n_lookup);
	proc_data.photons = (close_photon_t*)alloca(photon_map->n_lookup *
		sizeof(close_photon_t));
	float md2 = photon_map->max_dist_squared;
	map->Lookup(
		p,(proc_data),photon_process,md2
		);
	//accumulate irradiance value from nearby photons
	close_photon_t *photons = proc_data.photons;
	spectrum_t e;
	vclr(e);
	for (unsigned i = 0; i < proc_data.found_photons;++i)
	{
		if(vdot(n,photons[i].photon->wi) > 0.f)
		{
			vadd(e,e,photons[i].photon->alpha);
		}
	}
	vsmul(*ret,1.f/((float)count * md2 * FLOAT_PI),e);
}


void photon_map_destroy(photon_map_t* photon_map)//free up kd-tree memory
{
	delete photon_map->radiance_map_lookup;
	delete photon_map->indirect_map_lookup;
	delete photon_map->caustic_map_lookup;
	photon_map->indirect_map_lookup = NULL;
	photon_map->caustic_map_lookup = NULL;
	photon_map->radiance_map_lookup = NULL;
}



